#include "gwbase/base/atomic.h"
#include "gwbase/base/test_harness.h"
#include "gwbase/base/thread.h"
#include <boost/bind.hpp>

class AtomicTest 
{
 public:
  void Reset() {
    val_.Store_Release(0);
  }

  void AddVal(int32_t n) {
    for (int32_t i = 0; i < n; ++i) 
      val_.Increment();
  }

 protected:
  dicom::AtomicInt32 val_;
};


TEST(AtomicTest, SingleThread) {
  Reset();
  AddVal(1000);
  EXPECT_Eq(val_.Load_Acquire(), 1000);
}

TEST(AtomicTest, TwoThread) {
  Reset();
  const int32_t kCount = 100000;
  dicom::ThreadPtr t1(new dicom::Thread(
          boost::bind(&AtomicTest::AddVal, this, kCount), "t1"));
  dicom::ThreadPtr t2(new dicom::Thread(
          boost::bind(&AtomicTest::AddVal, this, kCount), "t2"));

  t1->Start();
  t2->Start();

  t1->Join();
  t2->Join();

  EXPECT_Eq(val_.Load_Acquire(), kCount*2);
}


int main() {
  dicom::RunAllTests();
  return 0;
}
